Java 2 has a security architecture that is intended to protect client and server systems from malicious code that has been dynamically installed (e.g., mobile code). For example, applet code can be downloaded from the Internet into a Web browser, or uploaded via RMI into a server application. The Java 2 security system includes an authentication subsystem and an authorization subsystem. In the discussion that follows, we will concern ourselves only with the authorization subsystem.
Java 2 authorization is based on a set of ProtectionDomains, where each Java application class is loaded via a SecureClassLoader into the Java virtual machine. In the reference implementation of the Java virtual machine, classes part of the Java runtime are loaded from the “boot classpath”, by a special class loader sometimes referred to as the “primordial class loader.” These classes are considered fully trusted and are implicitly given AllPermission. Each application class refers to a ProtectionDomain. This ProtectionDomain object includes a CodeSource and a set of Permissions. The CodeSource is authentication information (the code base URL, and the digital certificates used to sign the code if the code was signed). The Permissions are a set of
Permission objects representing the permissions, or rights, the code has with respect to privileged operations. It is the computation of this set of Permission objects that is the subject of this invention.
Prior to deploying (application or library) code in Java, an important question arises: “What Java Permission(s) are required to enable the code to run in a system which has the security authorization subsystem enabled?” Currently, this problem is solved empirically. The code writer reads the documentation for any libraries (including the Java runtime libraries) invoked by the code and determines whether any of these libraries requires that the code have specific Permission(s) in order to run. Unfortunately, this documentation is often missing information on used Permission(s), or the documentation is out of date. In the absence of reliable documentation, the developer runs the new code and waits until a SecurityException is thrown due to an insufficient set of Permission(s) allocated to the new code. The developer then adds any additional used Permission(s) to the set granted to the code under test. This trial-and-error process is repeated until no more SecurityException failures occur.
An analogous scenario can be depicted on the system where mobile code is dynamically installed. When mobile code is downloaded on a system, the system administrator (e.g., the web browser user) has to figure out what Permission(s) that code needs in order for it to work without causing SecurityException failures. The system administrator should therefore rely on what the code developer/distributor recommends, with the risk that too many Permission(s) are granted and security holes are opened. Alternatively, the system administrator should first run the code with no Permission(s), look at the SecurityExceptions thrown, and incrementally grant Permission(s) as is necessary. This process can be tedious and error-prone. In addition, insufficient code testing may result in a wrong set of Permission(s) being granted, which may cause security exposures or code instability.
Rather than relying on empirical, or ad hoc, methods of determining what Permission(s) are used to run application/library code, we describe a process by which the used Permission(s) for a software component (e.g., library, application, etc.) can be computed.